package com.tian.mybatis.session;

import com.tian.mybatis.config.Configuration;
import com.tian.mybatis.config.MapperStatement;

import java.lang.reflect.*;
import java.util.Map;

/**
 * @author tianwc  公众号：java后端技术全栈、面试专栏
 * @version 1.0.0
 * @date 2023年09月22日 16:09
 * 在线刷题 1200+题和1000+篇干货文章：<a href="https://woaijava.cc/">博客地址</a>
 */
public class MapperProxyFactory {


    /**
     * 使用JDK动态代理给UserMapper接口生一个实现类
     *
     * @param mapperClass UserMapper.class
     * @param <T>
     * @return
     */
    public <T> T getMapper(Class<T> mapperClass, Configuration configuration) {
        Object instance = Proxy.newProxyInstance(mapperClass.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //调用的方法名称
                String methodName = method.getName();
                //这个方法背定义在哪个接口中
                String className = method.getDeclaringClass().getName();
                //拼接SQL的唯一标识
                String statementId = className + "." + methodName;
                //获取方法调用之后的返回值类型（方法返回类型）
                Type genericReturnType = method.getGenericReturnType();

                Map<String, MapperStatement> mapperStatementMap = configuration.getMapperStatementMap();
                MapperStatement mapperStatement = mapperStatementMap.get(statementId);
                String sqlType = mapperStatement.getSqlType();
               /* if (sqlType.equals("update")) {
                    return update(statementId, args);
                } else if (sqlType.equals("insert")) {
                    return insert(statementId, args);
                } else if (sqlType.equals("dalete")) {
                    return dalete(statementId, args);
                }

                //表示我们查询返回的是否是泛型类型的参数化
                if (genericReturnType instanceof ParameterizedType) {
                    return selectList(statementId, args);
                } else {
                    //查询结果不是泛型
                    return selectOne(statementId, args);
                }*/
                return null;
            }
        });
        return (T) instance;
    }
}
